package com.un.ebs.workOrder.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.un.ebs.core.common.GroupListInfo;
import com.un.ebs.core.enums.PowerTypeEnum;
import com.un.ebs.core.enums.UserTypeEnum;
import com.un.ebs.core.exception.BusinessException;
import com.un.ebs.core.metadata.MetadataFunction;
import com.un.ebs.core.util.SecurityUtils;
import com.un.ebs.core.util.StringUtils;
import com.un.ebs.core.util.WebResult;
import com.un.ebs.core.util.WebUtils;
import com.un.ebs.customer.service.CustomerService;
import com.un.ebs.order.domain.OrderItemExt;
import com.un.ebs.order.service.OrderService;
import com.un.ebs.sys.domain.UserExt;
import com.un.ebs.sys.service.AppPowerService;
import com.un.ebs.sys.service.AppTenantService;
import com.un.ebs.sys.service.UserService;
import com.un.ebs.workOrder.domain.WorkOrderExt;
import com.un.ebs.workOrder.dto.*;
import com.un.ebs.workOrder.enums.RoleTypeEnum;
import com.un.ebs.workOrder.enums.WorkOrderStatusEnum;
import com.un.ebs.workOrder.mapper.WorkOrderExtMapper;
import com.un.ebs.workOrder.service.WorkOrderService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;


/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author liubo
 * @since 2019-11-18
 */
@RestController
@RequestMapping("/workOrder")
@Api(value = "work-order", tags = "")
public class WorkOrderController {

    @Autowired
    private WorkOrderService service;

    @Autowired
    private OrderService orderService;

    @Autowired
    private CustomerService customerService;

    @Autowired
    private WorkOrderExtMapper workOrderExtMapper;

    @Autowired
    private AppPowerService appPowerService;

    @Autowired
    private AppTenantService appTenantService;

    @Autowired
    private WxMpService wxService;

    @Autowired
    private UserService userService;

    private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分");

    private void sendAcceptMsg(String id) {
        WorkOrderExt workOrder = service.queryById(id);
        if (workOrder == null) {
            return;
        }

        List<UserExt> userExts = appPowerService.queryUserByResourcePower(workOrder.getSpuId(), PowerTypeEnum.Spu);

        for (UserExt user : userExts) {
            if (StringUtils.isNullOrEmpty(user.getOpenId())) {
                continue;
            }

            WxMpTemplateMessage templateMessage = WxMpTemplateMessage.builder()
                    .toUser(user.getOpenId())
                    .templateId("-ZYUUN3wmkYmjzCA702HtrZ7LLOvzAGw0NEENeSz6Cg")
                    .url("http://www.cloud-client.cn/ebs/weixin?entId=" + user.getEntId() + "&workOrderId=" + workOrder.getId())
                    .build();
            templateMessage.addData(new WxMpTemplateData("first", "你有新服务工单，请及时受理。"));
            templateMessage.addData(new WxMpTemplateData("keyword1", workOrder.getName() + "，" + workOrder.getSaleAttrDesc()));
            templateMessage.addData(new WxMpTemplateData("keyword2", sdf.format(workOrder.getStartTime())));
            templateMessage.addData(new WxMpTemplateData("remark", "请在上述时间之前受理并完成此服务。"));
            try {
                wxService.getTemplateMsgService().sendTemplateMsg(templateMessage);
            } catch (WxErrorException e) {
                e.printStackTrace();
            }
        }
    }

    @PostMapping("add")
    @ApiOperation(value = "step 1 : 添加", notes = "step 1 : 添加")
    public WebResult save(MultipartHttpServletRequest request) {
        MultipartHttpServletRequest multipartRequest = request;

        //表单中的四个参数
        String createOrderItemId = multipartRequest.getParameter("createOrderItemId");
        String createRemark = multipartRequest.getParameter("createRemark");
        String createRoleType = multipartRequest.getParameter("createRoleType");
        String createRoleId = multipartRequest.getParameter("createtRoleId");

        //提交的文件列表
        List<MultipartFile> files = multipartRequest.getFiles("file");
        WorkOrderAddDto addDto = new WorkOrderAddDto();
        addDto.setCreateOrderItemId(createOrderItemId);
        addDto.setCreateRemark(createRemark);
        addDto.setCreatetRoleId(createRoleId);
        if (RoleTypeEnum.User.toString().toLowerCase().equals(createRoleType.toLowerCase())) {
            addDto.setCreateRoleType(RoleTypeEnum.User);
        } else if (RoleTypeEnum.Customer.toString().toLowerCase().equals(createRoleType.toLowerCase())) {
            addDto.setCreateRoleType(RoleTypeEnum.Customer);
        }
        String id = service.add(addDto, files);

        sendAcceptMsg(id);

        //TO:DO 针对上面的数据做验证&保存
        return WebUtils.success();
    }

    @PostMapping("assign")
    @ApiOperation("订单项的交付分配")
    public WebResult assign(@RequestBody @Validated WorkOrderAssignDto req) {
        service.assign(req);
        return WebUtils.success();
    }

    @PostMapping("assignCancel")
    @ApiOperation("撤销订单项的交付分配")
    public WebResult assignCancel(@RequestParam String id) {
        service.assignCancel(id);
        return WebUtils.success();
    }

    @PostMapping("update")
    @ApiOperation(value = "update", notes = "修改")
    public WebResult update(@RequestBody WorkOrderUpdateDto req, @RequestParam(name = "file1", required = false) MultipartFile file1, @RequestParam(name = "file2", required = false) MultipartFile file2, @RequestParam(name = "file3", required = false) MultipartFile file3) {
        List<MultipartFile> list = new ArrayList<>();
        if (file1 != null) {
            list.add(file1);
        }
        if (file2 != null) {
            list.add(file2);
        }
        if (file3 != null) {
            list.add(file3);
        }
        service.update(req, list);
        return WebUtils.success();
    }

    @PostMapping("updatePlanDeliverTime")
    @ApiOperation("修改工单交付计划")
    public WebResult updatePlanDeliverTime(@RequestBody @Validated WorkOrderChangePlanCompleteTimeDto req) {
        service.updatePlanCompleteTime(req.getId(), req.getPlanCompleteTime(), req.getRemark());
        return WebUtils.success();
    }

    @PostMapping("updatePlanDeliverTimeBatch")
    @ApiOperation("修改工单交付计划，批量")
    public WebResult updatePlanDeliverTimeBatch(@RequestBody @Validated List<WorkOrderChangePlanCompleteTimeDto> req) {
        service.updatePlanCompleteTime(req);
        return WebUtils.success();
    }

    @MetadataFunction
    @PostMapping("submit")
    @ApiOperation(value = "step 2 : 提交", notes = "step 2 : 提交")
    public WebResult submit(@RequestParam String id) {
        service.submit(id);
        return WebUtils.success();
    }

    //    @PostMapping("accept")
//    @ApiOperation(value = "step 3 : 受理", notes = "step 3 : 受理")
    public WebResult accept1(@RequestParam String id,
                             @RequestParam(name = "remark", required = false) String remark,
                             @RequestParam(name = "files", required = false) MultipartFile[] files) {
        service.accept(id, remark, null);
        return WebUtils.success();
    }

    @PostMapping("accept")
    @ApiOperation(value = "step 3 : 受理", notes = "step 3 : 受理")
    public WebResult accept(MultipartHttpServletRequest request) {
        MultipartHttpServletRequest multipartRequest = request;

        //表单中的四个参数
        String id = multipartRequest.getParameter("id");
        if (StringUtils.isNullOrEmpty(id)) {
            throw new BusinessException("id 参数不能为空。");
        }
        String remark = multipartRequest.getParameter("remark");

        //提交的文件列表
        List<MultipartFile> files = multipartRequest.getFiles("file");

        service.accept(id, remark, files);
        return WebUtils.success();
    }


    @PostMapping("complete")
    @ApiOperation("step 4 : 完成")
    public WebResult complete(MultipartHttpServletRequest request) {
        MultipartHttpServletRequest multipartRequest = request;

        //表单中的四个参数
        String id = multipartRequest.getParameter("id");
        String remark = multipartRequest.getParameter("remark");
        String strQty = multipartRequest.getParameter("qty");
        String strPrice = multipartRequest.getParameter("price");

        //提交的文件列表
        List<MultipartFile> files = multipartRequest.getFiles("file");

        service.complete(id,
                remark,
                StringUtils.isNullOrEmpty(strQty) ? 0 : Double.valueOf(strQty),
                StringUtils.isNullOrEmpty(strPrice) ? 0 : Double.valueOf(strPrice),
                files);
        return WebUtils.success();
    }

    @PostMapping("completeAudit")
    @ApiOperation("step 5 : 完工确认")
    public WebResult completeAudit(@RequestParam String id, @RequestParam Boolean isPass, @RequestParam(required = false) String desc) {
        service.audit(id, isPass, desc);
        return WebUtils.success();
    }

    @PostMapping("evaluate")
    @ApiOperation(value = "step 5 : 评价", notes = "step 5 : 评价")
    public WebResult evaluate(@RequestParam String id, @RequestParam Integer score, @RequestParam String remark) {
        service.evaluate(id, score, remark);
        return WebUtils.success();
    }

    @GetMapping("/{id}")
    @ApiOperation(value = "getById", notes = "根据主键获取单个 WorkOrder")
    public WebResult getById(@PathVariable("id") String id) {
        return WebUtils.success(service.queryViewById(id));
    }

    @GetMapping("listStatusCount")
    @ApiOperation("工单状态统计与明细")
    public WebResult<List<GroupListInfo<WorkOrderExt>>> listStatusCount() {
        return WebUtils.success(service.queryStatusCount(SecurityUtils.getUserContent().getId()));
    }

    @GetMapping("list")
    @ApiOperation(value = "list", notes = "工单查询")
    public WebResult list(@RequestParam(required = false) @ApiParam("用户ID") String userId,
                          @RequestParam @ApiParam("工单状态") WorkOrderStatusEnum status,
                          @RequestParam(required = false) @ApiParam("default : 1") Integer pageIndex,
                          @RequestParam(required = false) @ApiParam("default : -1") Integer pageSize) {
        if (pageIndex == null) {
            pageIndex = 1;
        }
        if (pageSize == null) {
            pageSize = -1;
        }
        return WebUtils.success(service.query(userId, status, pageIndex, pageSize));
    }

    @GetMapping("listByCustomer")
    @ApiOperation("查询工单，按客户ID")
    public WebResult<IPage<WorkOrderExt>> queryByCustomer(@RequestParam String customerId, @RequestParam WorkOrderStatusEnum status, @RequestParam int pageSize, @RequestParam int pageIndex) {
        return WebUtils.success(service.queryByCustomer(customerId, status, pageSize, pageIndex));
    }

    @GetMapping("listByOrder")
    @ApiOperation("查询工单，按订单ID")
    public WebResult<IPage<WorkOrderExt>> queryByOrder(@RequestParam String orderId) {
        return WebUtils.success(service.queryViewByOrder(orderId));
    }

    @GetMapping("listReadyCreate")
    @ApiOperation("1、待分配的工单")
    public WebResult<WorkOrderHomePageGroupVo> listHomePageByReadyCreate() {
        return WebUtils.success(queryReadyCreate());
    }

    @GetMapping("listReadyAccept")
    @ApiOperation("2、待受理的工单")
    public WebResult<WorkOrderHomePageGroupVo> listHomePageByReadyAccept() {
        return WebUtils.success(queryReadyAccept());
    }

    @GetMapping("listReadyComplete")
    @ApiOperation("3、待完成的工单")
    public WebResult<WorkOrderHomePageGroupVo> listHomePageByReadyComplete() {
        return WebUtils.success(queryReadyComplete());
    }

    @GetMapping("listReadyEvaluate")
    @ApiOperation("4、待评价的工单")
    public WebResult<WorkOrderHomePageGroupVo> listHomePageByReadyEvaluate() {
        return WebUtils.success(queryReadyEvaluate());
    }

    @GetMapping("listCompleteHistory")
    @ApiOperation("5、历史工单")
    public WebResult<WorkOrderHomePageGroupVo> listHomePageByCompleteHistory() {
        return WebUtils.success(queryCompleteHistory());
    }


    @GetMapping("listHomePageData")
    @ApiOperation(value = "listHomePageData", notes = "获取工单的首页数据")
    public WebResult<WorkOrderHomePageVo> listHomePageData() {
        WorkOrderHomePageVo result = new WorkOrderHomePageVo();

        WorkOrderHomePageGroupVo g1 = queryReadyCreate();
        if (g1 != null) {
            result.getGroups().add(g1);
        }

        WorkOrderHomePageGroupVo g2 = queryReadyAccept();
        if (g2 != null) {
            result.getGroups().add(g2);
        }

        WorkOrderHomePageGroupVo g3 = queryReadyComplete();
        if (g3 != null) {
            result.getGroups().add(g3);
        }

        WorkOrderHomePageGroupVo g4 = queryReadyEvaluate();
        if (g4 != null) {
            result.getGroups().add(g4);
        }

        WorkOrderHomePageGroupVo g5 = queryCompleteHistory();
        if (g5 != null) {
            result.getGroups().add(g5);
        }

        return WebUtils.success(result);
    }

    private WorkOrderHomePageItemVo getItemVo(WorkOrderExt item, String type) {
        WorkOrderHomePageItemVo vo = new WorkOrderHomePageItemVo();
        vo.setId(item.getId());
        vo.setOrderCode(item.getOrderCode());
        vo.setCustAddress(item.getLinkmanAdd());
        vo.setRemark(item.getOrderItemRemark());
        vo.setSkuCode(item.getSkuCode());
        vo.setCustName(item.getCustName());
        vo.setPhone(item.getLinkmanPhone());
        vo.setSpuClassRootName(item.getClassRootName());
        vo.setSkuName(item.getName());
        vo.setSkuDesc(item.getName() + "，" + item.getSaleAttrDesc() + "，× " + item.getItemQty());
        vo.setDeliverQty(item.getItemQty());
        vo.setDeliverType(item.getDeliverType());
        vo.setTime(item.getCreateTime());
        if (StringUtils.isNullOrEmpty(item.getDefunctName())) {
            vo.setDefunctName(item.getName());
        } else {
            vo.setDefunctName(item.getDefunctName());
        }
        vo.setDefunctIdNumber(item.getDefunctIdNumber());
        vo.setDeliverUserId(item.getAcceptUserId());
        vo.setDeliverName(item.getAcceptUserName());
        vo.setType(type);
        return vo;
    }

    private WorkOrderHomePageGroupVo queryReadyCreate() {
        return new WorkOrderHomePageGroupVo("待分配");
    }

    /**
     * 需要工作人员受理的工单
     *
     * @return
     */
    private WorkOrderHomePageGroupVo queryReadyAccept() {
        WorkOrderHomePageGroupVo result = new WorkOrderHomePageGroupVo("未开始");
        List<WorkOrderHomePageItemVo> items = new ArrayList<>();

        LambdaQueryWrapper<WorkOrderExt> lq = Wrappers.lambdaQuery();
        lq.eq(WorkOrderExt::getCreateStatus, true);
        lq.eq(WorkOrderExt::getAcceptStatus, false);
        lq.eq(WorkOrderExt::getIsDelete, false);

        if (SecurityUtils.getUserContent().getType() == UserTypeEnum.OTHER) {
            List<String> ids = getCurrCustId();
            if (ids.size() <= 0) {
                return result;
            }

            lq.in(WorkOrderExt::getCustId, ids);
        } else {
            List<String> spuIds = appPowerService.queryResourcePower(PowerTypeEnum.Spu);
            if (spuIds.size() <= 0) {
                return result;
            }
            lq.in(WorkOrderExt::getSpuId, spuIds);
        }
        lq.orderByDesc(WorkOrderExt::getCreateTime);
        List<WorkOrderExt> list = workOrderExtMapper.selectList(lq);

        for (WorkOrderExt item : list) {
            items.add(getItemVo(item, "accept"));
        }
        if (items.size() > 0) {
            result.setItems(items);
            return result;
        }
        return result;
    }

    private WorkOrderHomePageGroupVo queryReadyComplete() {
        WorkOrderHomePageGroupVo result = new WorkOrderHomePageGroupVo("进行中");
        List<WorkOrderHomePageItemVo> items = new ArrayList<>();

        LambdaQueryWrapper<WorkOrderExt> lq = Wrappers.lambdaQuery();
        lq.eq(WorkOrderExt::getCreateStatus, true);
        lq.eq(WorkOrderExt::getAcceptStatus, true);
        lq.eq(WorkOrderExt::getCompleteStatus, false);

        if (SecurityUtils.getUserContent().getType() == UserTypeEnum.OTHER) {
            List<String> ids = getCurrCustId();
            if (ids.size() <= 0) {
                return result;
            }
            lq.in(WorkOrderExt::getCustId, ids);
        } else {
            lq.eq(WorkOrderExt::getAcceptUserId, SecurityUtils.getUserContent().getId());
        }

        lq.orderByDesc(WorkOrderExt::getAcceptTime);
        List<WorkOrderExt> list = workOrderExtMapper.selectList(lq);

        for (WorkOrderExt item : list) {
            items.add(getItemVo(item, "deliver"));
        }
        if (items.size() > 0) {
            result.setItems(items);
            return result;
        }
        return result;
    }

    private WorkOrderHomePageGroupVo queryReadyEvaluate() {
        WorkOrderHomePageGroupVo result = new WorkOrderHomePageGroupVo("已完成");
        List<WorkOrderHomePageItemVo> items = new ArrayList<>();

        Page<WorkOrderExt> page = new Page<>(1, 10);
        LambdaQueryWrapper<WorkOrderExt> lq = Wrappers.lambdaQuery();
        lq.eq(WorkOrderExt::getCompleteStatus, true);
        lq.eq(WorkOrderExt::getEvaluateStatus, false);
        lq.between(WorkOrderExt::getCompleteTime, LocalDate.now().atTime(LocalTime.MAX), LocalDate.now().atTime(LocalTime.MIN));
        if (SecurityUtils.getUserContent().getType() == UserTypeEnum.OTHER) {
            List<String> ids = getCurrCustId();
            if (ids.size() <= 0) {
                return result;
            }
            lq.in(WorkOrderExt::getCustId, ids);
        } else {
            lq.eq(WorkOrderExt::getCompleteUserId, SecurityUtils.getUserContent().getId());
        }

        lq.orderByDesc(WorkOrderExt::getCompleteTime);
        List<WorkOrderExt> list = workOrderExtMapper.selectPage(page, lq).getRecords();

        for (WorkOrderExt item : list) {
            items.add(getItemVo(item, "evaluate"));
        }
        if (items.size() > 0) {
            result.setItems(items);
            return result;
        }
        return result;
    }

    private WorkOrderHomePageGroupVo queryCompleteHistory() {
        WorkOrderHomePageGroupVo result = new WorkOrderHomePageGroupVo("已完成");
        List<WorkOrderHomePageItemVo> items = new ArrayList<>();

        Page<WorkOrderExt> page = new Page<>(1, 10);
        LambdaQueryWrapper<WorkOrderExt> lq = Wrappers.lambdaQuery();
        lq.eq(WorkOrderExt::getEvaluateStatus, true);
        if (SecurityUtils.getUserContent().getType() == UserTypeEnum.OTHER) {
            List<String> ids = getCurrCustId();
            if (ids.size() <= 0) {
                return null;
            }
            lq.in(WorkOrderExt::getCustId, ids);
        } else {
            lq.eq(WorkOrderExt::getAcceptUserId, SecurityUtils.getUserContent().getId());
        }
        lq.orderByDesc(WorkOrderExt::getEvaluateTime);
        List<WorkOrderExt> list = workOrderExtMapper.selectPage(page, lq).getRecords();

        for (WorkOrderExt item : list) {
            items.add(getItemVo(item, "history"));
        }
        if (items.size() > 0) {
            result.setItems(items);
            return result;
        }
        return null;
    }

    private List<String> getCurrCustId() {
        return customerService.queryCustIdByUserId(SecurityUtils.getUserContent().getId());
    }


}